package com.agent.gateway.filter;

import com.agent.common.entity.UserContext;
import com.agent.common.exception.AuthenticationException;
import com.agent.common.result.ResultCode;
import com.agent.common.utils.JwtUtils;
import com.agent.common.utils.TokenInfoUtils;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * JWT认证过滤器
 *
 * @author Jeff_Wan
 * @description 处理JWT认证的网关过滤器
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class JwtAuthFilter extends AbstractGatewayFilterFactory<JwtAuthFilter.Config> {

    private final JwtUtils jwtUtils;

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();

            // 获取Authorization头
            String authHeader = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
            if (!StringUtils.hasText(authHeader) || !authHeader.startsWith("Bearer ")) {
                throw new AuthenticationException(ResultCode.UNAUTHORIZED, "Missing or invalid Authorization header");
            }

            // 提取JWT令牌
            String token = authHeader.substring(7);

            try {
                // 验证JWT令牌
                boolean isValid = jwtUtils.validateRsaToken(token);

                if (isValid) {
                    // 从令牌中提取用户信息
                    UserContext userContext = TokenInfoUtils.extractUserContextFromToken(token, jwtUtils);

                    // 添加用户信息到请求头
                    ServerHttpRequest modifiedRequest = request.mutate()
                            .header("X-User-Id", userContext.getUserId().toString())
                            .header("X-Username", userContext.getUsername())
                            .header("X-Membership-Type", userContext.getMembershipType())
                            .build();

                    return chain.filter(exchange.mutate().request(modifiedRequest).build());
                } else {
                    throw new AuthenticationException(ResultCode.UNAUTHORIZED, "Invalid token");
                }
            } catch (Exception e) {
                throw new AuthenticationException(ResultCode.UNAUTHORIZED, "Token validation failed: " + e.getMessage());
            }
        };
    }

    /**
     * 过滤器配置类
     */
    @Data
    public static class Config {
        /**
         * 排除认证的路径列表
         */
        private List<String> excludePaths;
    }
}